//! pGina winLDAP plugin
/*!

Some code has been taken from ldapAuth_plus. Please observe their licenses as well if you use 
develop based upon this code.


LTIA - Applied Information Technology Lab
UNESP - Univ Estadual Paulista, Bauru

*/

#include "stdafx.h"
#include "winLDAP.h"
#include "ConfigLDAP.h"
#include ".\configldap.h"



// CConfigLDAP dialog

IMPLEMENT_DYNAMIC(CConfigLDAP, CDialog)
CConfigLDAP::CConfigLDAP(CWnd* pParent /*=NULL*/)
	: CDialog(CConfigLDAP::IDD, pParent)
	, m_server(_T(""))
	, m_ldapPrePend(_T(""))
	, m_ldapAppend(_T(""))
	, m_ldapAdminUsername(_T(""))
	, m_ldapAdminPassword(_T(""))
	, m_useSSL(FALSE)
	, m_port(_T(""))
	, m_timeout(_T(""))
	, m_ldapFilter(_T(""))
	, m_ldapGroupAttr(_T(""))
	, m_searchMode(FALSE)
	, m_multiMap(FALSE)
	, m_mapMode(FALSE)
	, m_newContext(_T(""))
{
	CString temp;
	DWORD dwdTmp;
	m_server = regReadString(L"ldapServer");	
	m_ldapPrePend = regReadString(L"ldapPrePend");
	m_ldapAppend = regReadString(L"ldapAppend");
	m_ldapAdminUsername = regReadString(L"ldapAdminUsername");
	m_ldapAdminPassword = ReadProtectedStringValueFromRegistry(L"ldapAdminPassword");
	m_port.Format(L"%d",regReadDword(L"ldapPort"));
	m_timeout.Format(L"%d",regReadDword(L"ldapTimeout"));
	m_ldapFilter = regReadString(L"ldapFilter");
	m_ldapGroupAttr = regReadString(L"ldapGroupAttr");

	dwdTmp = regReadDword(L"useSSL");
	if(dwdTmp == 1)
		m_useSSL = true;
	else
		m_useSSL = false;
	
	dwdTmp = regReadDword(L"ldapMethod");
	if(dwdTmp == 1) 
	{
		m_multiMap = true;
	}
	else if(dwdTmp == 2) 
	{
		m_searchMode = true;
	}
	else if(dwdTmp == 3) {
		m_mapMode = true;
	}

	hasLoaded = false;
}

BOOL CConfigLDAP::OnInitDialog() 
{
	CString temp;
	DWORD dwdTmp;
	CDialog::OnInitDialog();

	dwdTmp = regReadDword(L"ldapMethod");
	if(dwdTmp == 1) {
		m_multiMap = true;
		c_ldapAppend.EnableWindow (false);
		c_ldapPrePend.EnableWindow (false);

		// Enable Context fields
		m_ContextList.EnableWindow (true);
		c_newcontext.EnableWindow(true);
		c_addcontext.EnableWindow(true);
		c_delcontext.EnableWindow(true);
		c_upcontext.EnableWindow(true);
		c_downcontext.EnableWindow(true);
	}
	else if(dwdTmp == 2) {
		m_searchMode = true;
		c_ldapAppend.EnableWindow (false);
		c_ldapPrePend.EnableWindow (false);

		// Enable Context fields
		m_ContextList.EnableWindow (true);
		c_newcontext.EnableWindow(true);
		c_addcontext.EnableWindow(true);
		c_delcontext.EnableWindow(true);
		c_upcontext.EnableWindow(true);
		c_downcontext.EnableWindow(true);
	}
	else if(dwdTmp == 3) {
		m_mapMode = true;
		c_ldapAppend.EnableWindow (true);
		c_ldapPrePend.EnableWindow (true);

		// Disable Context fields
		m_ContextList.EnableWindow (false);
		c_newcontext.EnableWindow(false);
		c_addcontext.EnableWindow(false);
		c_delcontext.EnableWindow(false);
		c_upcontext.EnableWindow(false);
		c_downcontext.EnableWindow(false);
	}

	return TRUE; // Return TRUE unless you set the focus to a control.
				 // EXCEPTION: OCX Property Pages should return FALSE
}

CConfigLDAP::~CConfigLDAP()
{
//	EnableHtmlHelp();
}

void CConfigLDAP::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_LDAPSERVER, m_server);
	DDX_Text(pDX, IDC_LDAPPREPEND, m_ldapPrePend);
	DDX_Text(pDX, IDC_LDAPAPPEND, m_ldapAppend);
	DDX_Text(pDX, IDC_ADMINUSERNAME, m_ldapAdminUsername);
	DDX_Text(pDX, IDC_ADMINPASSWORD, m_ldapAdminPassword);
	DDX_Check(pDX, IDC_USESSL, m_useSSL);
	DDX_Text(pDX, IDC_PORT, m_port);
	DDX_Text(pDX, IDC_LDAPFILTER, m_ldapFilter);
	DDX_Text(pDX, IDC_LDAPGROUPATTR, m_ldapGroupAttr);
	DDX_Check(pDX, IDC_SEARCH, m_searchMode);
	DDX_Check(pDX, IDC_MULTIMAP, m_multiMap);
	DDX_Check(pDX, IDC_MAP, m_mapMode);
	DDX_Control(pDX, IDC_CONTEXTLIST, m_ContextList);
	DDX_Text(pDX, IDC_NEWCONTEXT, m_newContext);
	DDX_Text(pDX, IDC_TIMEOUT, m_timeout);

	if(!hasLoaded)
	{
		loadListsFromReg();
		hasLoaded = true;
	}

	DDX_Control(pDX, IDC_LDAPPREPEND, c_ldapPrePend);
	DDX_Control(pDX, IDC_LDAPAPPEND, c_ldapAppend);
	DDX_Control(pDX, IDC_NEWCONTEXT, c_newcontext);
	DDX_Control(pDX, IDC_ADDCONTEXTBUTTON, c_addcontext);
	DDX_Control(pDX, IDC_DELCONTEXTBUTTON, c_delcontext);
	DDX_Control(pDX, IDC_MOVECTXUP, c_upcontext);
	DDX_Control(pDX, IDC_MOVECTXDWN, c_downcontext);
	DDX_Control(pDX, IDC_USESSL, c_usessl);
}


BEGIN_MESSAGE_MAP(CConfigLDAP, CDialog)
	ON_BN_CLICKED(IDC_ADDCONTEXTBUTTON, OnAddContext)
	ON_BN_CLICKED(IDC_DELCONTEXTBUTTON, OnRemoveContext)
	ON_BN_CLICKED(IDC_MOVECTXUP, OnMoveContextUp)
	ON_BN_CLICKED(IDC_MOVECTXDWN, OnMoveContextDown)
	ON_BN_CLICKED(IDC_SEARCH, OnChangeSearch)
	ON_BN_CLICKED(IDC_MULTIMAP, OnChangeMultimap)
	ON_BN_CLICKED(IDC_MAP, OnChangeMapMode)
	ON_EN_CHANGE(IDC_LDAPFILTER, OnEnChangeLdapfilter)
END_MESSAGE_MAP()


// CConfigLDAP message handlers

void CConfigLDAP::OnOK()
{
	return;
}

void CConfigLDAP::OnAddContext()
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	if (m_newContext == "") {
		MessageBox(L"Please enter a valid context.", L"LDAPAuth", MB_OK);
		return;
	}
	m_ContextList.AddString(m_newContext);
	m_newContext = TEXT("");
	UpdateData(FALSE);
}

void CConfigLDAP::OnRemoveContext()
{
	// TODO: Add your control notification handler code here
	if(m_ContextList.GetCurSel() >= 0)
		m_ContextList.DeleteString(m_ContextList.GetCurSel());
}

void CConfigLDAP::OnMoveContextUp()
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	// TODO: Add your control notification handler code here
	if(m_ContextList.GetCurSel() > 0)
		swapItem(&m_ContextList,m_ContextList.GetCurSel(),m_ContextList.GetCurSel() - 1);

	UpdateData(FALSE);
}

void CConfigLDAP::OnMoveContextDown()
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	// TODO: Add your control notification handler code here
	if(m_ContextList.GetCurSel() >= 0 && m_ContextList.GetCurSel() < m_ContextList.GetCount() - 1)
		swapItem(&m_ContextList,m_ContextList.GetCurSel(),m_ContextList.GetCurSel() + 1);

	UpdateData(FALSE);
}

void CConfigLDAP::OnChangeSearch()
{
	// TODO: Add your control notification handler code here
	 //m_searchMode
	 //m_multiMap
	//m_mapMode
	UpdateData(TRUE);
	if(m_searchMode)
	{
		m_multiMap = false;
		m_mapMode = false;
		// Begin code to disable options inappropriate for multimap
		// disable IDC_LDAPAPPEND
		c_ldapAppend.EnableWindow (false);
		c_ldapPrePend.EnableWindow (false);

		m_ContextList.EnableWindow (true);
		c_newcontext.EnableWindow(true);
		c_addcontext.EnableWindow(true);
		c_delcontext.EnableWindow(true);
		c_upcontext.EnableWindow(true);
		c_downcontext.EnableWindow(true);
	}
	if(!m_searchMode) // if they try to uncheck it
		m_searchMode = true; // dont let them
	UpdateData(FALSE);
}

void CConfigLDAP::OnChangeMultimap()
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	if(m_multiMap)
	{
		m_searchMode = false;
		m_mapMode = false;
		// Begin code to disable options inappropriate for multimap
		// disable IDC_LDAPAPPEND
		c_ldapAppend.EnableWindow (false);
		c_ldapPrePend.EnableWindow (true);

		m_ContextList.EnableWindow (true);
		c_newcontext.EnableWindow(true);
		c_addcontext.EnableWindow(true);
		c_delcontext.EnableWindow(true);
		c_upcontext.EnableWindow(true);
		c_downcontext.EnableWindow(true);
	}
	if(!m_multiMap) // if they try to uncheck it
		m_multiMap = true; // dont let them
	
	UpdateData(FALSE);
}

void CConfigLDAP::OnChangeMapMode()
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	if(m_mapMode)
	{
		m_searchMode = false;
		m_multiMap = false;
		// Begin code to disable options inappropriate for multimap
		// disable IDC_LDAPAPPEND
		c_ldapAppend.EnableWindow (true);
		c_ldapPrePend.EnableWindow (true);

		m_ContextList.EnableWindow (false);
		c_newcontext.EnableWindow(false);
		c_addcontext.EnableWindow(false);
		c_delcontext.EnableWindow(false);
		c_upcontext.EnableWindow(false);
		c_downcontext.EnableWindow(false);
	}
	if(!m_mapMode) // if they try to uncheck it
		m_mapMode = true; // dont let them
	
	UpdateData(FALSE);
}

void CConfigLDAP::OnSave()
{
	UpdateData(TRUE);

	// Save data to registry
	CString temp;

	if(m_server.GetLength() > 0)
		regWriteString(m_server.GetBuffer(m_server.GetLength()),L"ldapServer");
	else
		regDelValue(L"ldapServer");
	
	if(m_ldapPrePend.GetLength() > 0)
		regWriteString(m_ldapPrePend.GetBuffer(m_ldapPrePend.GetLength()),L"ldapPrePend");
	else
		regDelValue(L"ldapPrePend");

	if(m_ldapAppend.GetLength() > 0)
		regWriteString(m_ldapAppend.GetBuffer(m_ldapAppend.GetLength()),L"ldapAppend");
	else
		regDelValue(L"ldapAppend");

	if(m_ldapAdminUsername.GetLength() > 0)
        regWriteString(m_ldapAdminUsername.GetBuffer(m_ldapAdminUsername.GetLength()),L"ldapAdminUsername");
	else
		regDelValue(L"ldapAdminUsername");

	if(m_ldapAdminPassword.GetLength() > 0)
		WriteProtectedStringValueToRegistry(m_ldapAdminPassword.GetBuffer(m_ldapAdminPassword.GetLength()),L"ldapAdminPassword");
	else
		ReadProtectedStringValueFromRegistry(L"ldapAdminPassword");

	if(m_port.GetLength() > 0)
		regWriteDword(_wtoi(m_port.GetBuffer(m_port.GetLength())),L"ldapPort");
		//regWriteString(m_port.GetBuffer(m_port.GetLength()),L"ldapPort");
	else
		regDelValue(L"ldapPort");

	if(m_timeout.GetLength() > 0)
		regWriteDword(_wtoi(m_timeout.GetBuffer(m_port.GetLength())),L"ldapTimeout");
	else
		regDelValue(L"ldapPort");

	if(m_ldapFilter.GetLength() > 0)
		regWriteString(m_ldapFilter.GetBuffer(m_ldapFilter.GetLength()),L"ldapFilter");
	else
		regDelValue(L"ldapFilter");

	if(m_ldapGroupAttr.GetLength() > 0)
		regWriteString(m_ldapGroupAttr.GetBuffer(m_ldapGroupAttr.GetLength()),L"ldapGroupAttr");
	else
		regDelValue(L"ldapGroupAttr");

	if(m_useSSL)
		regWriteDword(1,L"useSSL");
	else
		regWriteDword(0,L"useSSL");

	if(m_multiMap)
		regWriteDword(1,L"ldapMethod");

	if(m_searchMode)
		regWriteDword(2,L"ldapMethod");

	if(m_mapMode)
		regWriteDword(3,L"ldapMethod");

	saveListsToReg();
}

void CConfigLDAP::loadListsFromReg(void)
{
	// Load the content for the lists from the registry 
	WCHAR currentName[256];
	int x = 0;
	CString contextValue = NULL;
	
	// Do contexts first
	swprintf(currentName,TEXT("ldapContext%d"),x);
	contextValue = regReadString(currentName);
	while(contextValue.GetLength() > 0)
	{
		m_ContextList.AddString(contextValue);
		x++;
        swprintf(currentName,TEXT("ldapContext%d"),x);
		contextValue = regReadString(currentName);
	}
}

void CConfigLDAP::saveListsToReg(void)
{
	WCHAR currentName[256];
	CString value = NULL;
	int x = 0;

	// First is contexts, save them
	for(x = 0; x < m_ContextList.GetCount(); x++)
	{
		m_ContextList.GetText(x,value);
		swprintf(currentName,TEXT("ldapContext%d"),x);
		regWriteString(value.GetBuffer(value.GetLength()),currentName);
	}

	// Now loop through and delete any existing contexts above our last saved one
	x = m_ContextList.GetCount();
	swprintf(currentName,TEXT("ldapContext%d"),x);
	value = regReadString(currentName);

	while(value.GetLength() > 0)
	{
		regDelValue(currentName);
		x++;
		swprintf(currentName,TEXT("ldapContext%d"),x);
		value = regReadString(currentName);
	}
}

void CConfigLDAP::swapItem(CListBox *listbox,int old, int next)
{
	CString valueA;
	CString valueB;
	

	listbox->GetText(old,valueA);
	listbox->DeleteString(old);
	listbox->InsertString(next,valueA);	
	listbox->SetCurSel(next);
}

void CConfigLDAP::OnEnChangeLdapfilter()
{
	// TODO:  If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.

	// TODO:  Add your control notification handler code here
}


